package net.weamor.ichat.cim.handler;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Map;

import net.weamor.ichat.common.util.Base64Coder;

import org.apache.log4j.Logger;

import com.farsunset.cim.nio.constant.CIMConstant;
import com.farsunset.cim.nio.handler.CIMRequestHandler;
import com.farsunset.cim.nio.model.ObjectConvertUtil;
import com.farsunset.cim.nio.model.ResponseFile;
import com.farsunset.cim.nio.mutual.ReplyBody;
import com.farsunset.cim.nio.mutual.SentBody;
import com.farsunset.cim.nio.session.CIMSession;

/**
 * 文件传输实现
 * @ClassName FileTransHandler  
 * @Description 客户端传输文件到服务器
 * @author weamor@163.com 
 * @date 2015-5-11  
 *   
 */
public class FileTransHandler implements CIMRequestHandler {

	private volatile int byteRead;
	protected final Logger logger = Logger.getLogger(FileTransHandler.class);
	
	private String fileDir = getTomcatPath("/uploadFileTemp");
	private File file;
	private long fileSize = -1;
	private RandomAccessFile randomAccessFile;

	public ReplyBody process(CIMSession newSession, SentBody message) {

		ReplyBody reply = new ReplyBody();
		reply.setKey("1001");
		reply.setCode(CIMConstant.ReturnCode.CODE_200);
		long start = 0;
		try {

			Map<String, String> paramMap = message.getData();
			String fileName = paramMap.get("fileName");
			String bytesStr = paramMap.get("bytes");
//			String startPos = paramMap.get("startPos");
			String endPos = paramMap.get("endPos");
			String fileMd5 = paramMap.get("fileMd5");
			String fileType = paramMap.get("fileType");
			String fileSize2 = paramMap.get("fileSize");
			
			byte[] bytes = Base64Coder.decode(bytesStr);
			byteRead = Integer.parseInt(endPos);
			String md5 = fileMd5;

			//为了防止start没有重置，需要奖start存储到session中
			Object objStart = newSession.getAttribute("start");
			
			if (objStart != null) {
				start = (Long)objStart;
			}
			
			if (start == 0 ) {
				String path = fileSavePath(md5, fileType);
				file = new File(path);
				System.out.println("path:" + path);
				fileSize = Long.parseLong(fileSize2);
				
				// 根据 MD5 和 文件类型 来确定是否存在这样的文件 如果存在就 秒传
				if (file.exists()) {
					logger.info("file exists:" + fileName + "--"
							+ fileMd5 + "["
							+ newSession.getRemoteAddress() + "]" + "cruuentSize:"
							+ file.length());
					// 实现续传，将服务器的文件长度返回给客户端
					start = file.length();

					// 如果还没有传完，那么就继续
					if (byteRead > 0 && (start < fileSize && fileSize != -1)) {
						ResponseFile responseFile = new ResponseFile(start,
								md5, (start * 100) / fileSize,"0000");
						reply.setMessage(ObjectConvertUtil.request(responseFile));

						closeRandomFile();
					} else if (start == fileSize) {
						// 传输完成
						System.out.println("传输完成................");
						ResponseFile responseFile = 
							new ResponseFile(start,md5, "","0000");
						start = 0;
						reply.setMessage(ObjectConvertUtil.request(responseFile));
						closeRandomFile();
					} else {
						// 这里表示上传失败
						ResponseFile responseFile = 
							new ResponseFile(start,md5, "","-3003");
						reply.setMessage(ObjectConvertUtil.request(responseFile));
						closeRandomFile();
					}
					return reply;
				}
			}
			
			randomAccessFile = new RandomAccessFile(file, "rw");
			System.out.println("randomAccessFile:" + randomAccessFile);
			randomAccessFile.seek(start);
			randomAccessFile.write(bytes);

			start = start + byteRead;
			// 如果还没有传完，那么就继续
			if (byteRead > 0 && (start < fileSize && fileSize != -1)) {
				ResponseFile responseFile = new ResponseFile(start, md5,
						(start * 100) / fileSize,"0000");
				reply.setMessage(ObjectConvertUtil.request(responseFile));
				closeRandomFile();
			} else if (start == fileSize) {
				// 传输完成
				System.out.println("传输完成................");
				ResponseFile responseFile = 
					new ResponseFile(start,md5, "","0000");
				start = 0;
				reply.setMessage(ObjectConvertUtil.request(responseFile));
				closeRandomFile();
			} else {
				// 这里表示上传失败
				ResponseFile responseFile = 
					new ResponseFile(start,md5, "","-3003");
				reply.setMessage(ObjectConvertUtil.request(responseFile));
				closeRandomFile();
			}
		} catch (Exception e) {
			reply.setCode(CIMConstant.ReturnCode.CODE_500);
			e.printStackTrace();
		}
		
		//最后要将start缓存到session
		newSession.setAttribute("start", start);
		
		
		logger.debug("trans file :account:" + message.get("account")
				+ "-----------------------------" + reply.getCode());
		return reply;
	}

	/**
	 * 定义文件保存路径和格式
	 * @Title: fileSavePath
	 * @param md5 文件MD5
	 * @param fileType
	 *            类别
	 * @throws
	 */
	private String fileSavePath(String md5, String fileType) {
		// 先判断下路径是否存在
		File dirPath = new File(fileDir);
		if (!dirPath.exists()) {
			dirPath.mkdirs();
		}
		String path = fileDir + "/" + md5 + fileType;
		return path;
	}
	
	public String getTomcatPath(String path) {
		String nowPath;
		String tempPath;
		nowPath = System.getProperty("user.dir");
		tempPath = nowPath.replace("bin", "webapps");
		if(tempPath.contains("webapps")){
			tempPath += "/" + path;
		}else{
			tempPath += "/webapps/" + path;
		}
		return tempPath;
	}
	
	private void closeRandomFile(){
		if (randomAccessFile != null) {
			try {
				randomAccessFile.close();
				randomAccessFile = null;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}